require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const fs = require('fs-extra');
const path = require('path');
const moment = require('moment');

const app = express();
const port = process.env.PORT || 3030;

// 使用中间件
app.use(cors());
app.use(bodyParser.json());

// 配置数据存储路径
const DATA_DIR = path.join(__dirname, 'data');
const MESSAGES_DIR = path.join(__dirname, 'messages');
const PUBLIC_CHAT_FILE = path.join(MESSAGES_DIR, 'public_chat.json');
const KFS_FILE = path.join(DATA_DIR, 'kfs.json');
const KFIT_FILE = path.join(DATA_DIR, 'kfit.json');

// 确保目录存在
fs.ensureDirSync(DATA_DIR);
fs.ensureDirSync(MESSAGES_DIR);

// 速率限制存储
const rateLimits = {};

// 开发者数据库缓存
let developersDB = {};
let authToUsernameMap = {};

// 日志函数 - 带时间戳和颜色
function log(message, type = 'info') {
    const timestamp = moment().format('YYYY-MM-DD HH:mm:ss');
    const colors = {
        info: '\x1b[36m', // 青色
        success: '\x1b[32m', // 绿色
        warning: '\x1b[33m', // 黄色
        error: '\x1b[31m', // 红色
        debug: '\x1b[35m' // 紫色
    };
    const reset = '\x1b[0m';
    
    const color = colors[type] || colors.info;
    console.log(`${color}[${timestamp}] ${message}${reset}`);
}

// 加载开发者数据库
function loadDevelopersDB() {
    try {
        if (!fs.existsSync(KFS_FILE)) {
            fs.writeJsonSync(KFS_FILE, {});
            log('已创建空的kfs.json文件', 'warning');
            return;
        }
        
        const kfsData = fs.readJsonSync(KFS_FILE);
        developersDB = kfsData;
        
        // 创建auth_id到用户名的映射
        authToUsernameMap = {};
        for (const username in developersDB) {
            if (developersDB[username] && developersDB[username].auth_id) {
                authToUsernameMap[developersDB[username].auth_id] = username;
            }
        }
        
        log(`已加载 ${Object.keys(developersDB).length} 名开发者`, 'success');
        log(`创建了 ${Object.keys(authToUsernameMap).length} 个鉴权ID映射`, 'debug');
    } catch (error) {
        log(`加载开发者数据库失败: ${error.message}`, 'error');
    }
}

// 确保API计数文件存在
function ensureKfitFile() {
    if (!fs.existsSync(KFIT_FILE)) {
        try {
            fs.writeJsonSync(KFIT_FILE, {});
            log(`已创建API计数文件: ${KFIT_FILE}`, 'success');
        } catch (err) {
            log(`无法创建API计数文件: ${err.message}`, 'error');
        }
    }
}

// 更新API调用计数
function updateAPICount(username) {
    try {
        // 确保文件存在
        ensureKfitFile();
        
        // 读取现有计数
        let counts = {};
        try {
            counts = fs.readJsonSync(KFIT_FILE);
        } catch (err) {
            log(`读取API计数文件失败: ${err.message}`, 'error');
        }
        
        // 更新计数
        if (counts[username] === undefined) {
            counts[username] = 1;
        } else {
            counts[username] += 1;
        }
        
        // 保存文件
        fs.writeJsonSync(KFIT_FILE, counts, { spaces: 2 });
        
        log(`已更新API计数: ${username} => ${counts[username]}`, 'debug');
        return counts[username];
    } catch (error) {
        log(`更新API计数失败: ${error.message}`, 'error');
        return -1;
    }
}

// 根据鉴权ID获取开发者用户名
function getDeveloperName(auth_id) {
    const username = authToUsernameMap[auth_id] || null;
    if (username) {
        log(`找到开发者: ${auth_id} => ${username}`, 'debug');
    } else {
        log(`未找到开发者: ${auth_id}`, 'warning');
    }
    return username;
}

// 保存消息到文件
function saveMessage(message) {
    try {
        // 确保文件存在
        if (!fs.existsSync(PUBLIC_CHAT_FILE)) {
            fs.writeFileSync(PUBLIC_CHAT_FILE, JSON.stringify([]));
            log('已创建公共聊天文件', 'success');
        }
        
        // 读取现有消息
        let messages = [];
        try {
            const content = fs.readFileSync(PUBLIC_CHAT_FILE, 'utf8');
            messages = JSON.parse(content);
        } catch (err) {
            log(`读取聊天文件失败: ${err.message}`, 'error');
        }
        
        // 添加新消息
        messages.push(message);
        
        // 保存文件
        fs.writeFileSync(PUBLIC_CHAT_FILE, JSON.stringify(messages, null, 2));
        
        log(`已保存消息: ${message.user} - ${message.content.substring(0, 20)}...`, 'debug');
        return true;
    } catch (error) {
        log(`保存消息失败: ${error.message}`, 'error');
        return false;
    }
}

// 发送公共消息API端点
app.post('/send_public', (req, res) => {
    const { auth_id, message_type, content } = req.body;
    
    log(`收到请求: ${req.method} ${req.url}`, 'info');
    log(`请求体: ${JSON.stringify(req.body)}`, 'debug');
    
    // 1. 验证必填字段
    if (!auth_id || !content || message_type !== 'public') {
        const errorMsg = '缺少必填字段或消息类型错误';
        log(`验证失败: ${errorMsg}`, 'warning');
        
        return res.status(400).json({
            success: false,
            error: errorMsg,
            received_data: req.body
        });
    }
    
    // 2. 根据鉴权ID获取用户名
    const username = getDeveloperName(auth_id);
    if (!username) {
        const errorMsg = '无效的鉴权ID';
        log(`鉴权失败: ${errorMsg}`, 'warning');
        
        return res.status(401).json({
            success: false,
            error: errorMsg,
            auth_id: auth_id,
            documentation: "https://developer.jiil-chat.com/docs/authentication"
        });
    }
    
    // 3. 速率限制检查
    const now = Date.now();
    
    // 初始化客户端速率限制记录
    if (!rateLimits[auth_id]) {
        rateLimits[auth_id] = {
            lastRequest: 0,
            requestsThisMinute: 0,
            minuteStart: Math.floor(now / 60000)
        };
        log(`初始化速率限制: ${auth_id}`, 'debug');
    }
    
    const clientRate = rateLimits[auth_id];
    
    // 检查每分钟限制 (每分钟最多10次)
    const currentMinute = Math.floor(now / 60000);
    if (currentMinute !== clientRate.minuteStart) {
        clientRate.requestsThisMinute = 0;
        clientRate.minuteStart = currentMinute;
        log(`重置分钟计数器: ${auth_id}`, 'debug');
    }
    
    if (clientRate.requestsThisMinute >= 10) {
        const errorMsg = '已超出每分钟请求限制(10次)';
        log(`速率限制: ${errorMsg}`, 'warning');
        
        return res.status(429).json({
            success: false,
            error: errorMsg,
            retry_after: 60 - (now - clientRate.minuteStart * 60000) / 1000
        });
    }
    
    // 检查每秒限制 (每秒最多1次)
    if (now - clientRate.lastRequest < 1000) {
        const errorMsg = '请求过于频繁，请稍后再试(1秒)';
        log(`速率限制: ${errorMsg}`, 'warning');
        
        return res.status(429).json({
            success: false,
            error: errorMsg,
            retry_after: 1 - (now - clientRate.lastRequest) / 1000
        });
    }
    
    // 4. 创建消息对象
    const message = {
        user: username,
        content: `[机器人] ${content}`,
        timestamp: new Date().toISOString()
    };
    
    // 5. 保存消息
    const saved = saveMessage(message);
    
    if (!saved) {
        const errorMsg = '服务器内部错误，无法保存消息';
        log(`保存失败: ${errorMsg}`, 'error');
        
        return res.status(500).json({
            success: false,
            error: errorMsg
        });
    }
    
    // 6. 更新API调用计数
    const newCount = updateAPICount(username);
    
    // 7. 更新速率限制计数器
    clientRate.lastRequest = now;
    clientRate.requestsThisMinute += 1;
    
    log(`请求处理成功: ${username} (${auth_id})`, 'success');
    
    // 8. 返回成功响应
    res.json({
        success: true,
        message: '消息发送成功',
        timestamp: message.timestamp,
        api_count: newCount
    });
});

// 404处理
app.use((req, res) => {
    log(`404错误: ${req.method} ${req.url}`, 'warning');
    
    res.status(404).json({
        success: false,
        error: 'Endpoint not found',
        requested_url: req.url,
        method: req.method
    });
});

// 错误处理中间件
app.use((err, req, res, next) => {
    log(`服务器错误: ${err.stack}`, 'error');
    
    res.status(500).json({
        success: false,
        error: '服务器内部错误',
        error_code: 'INTERNAL_SERVER_ERROR'
    });
});

// 启动服务器
app.listen(port, () => {
    log(`JIIL微聊后端服务正在运行: http://localhost:${port}`, 'success');
    
    // 加载开发者数据库
    loadDevelopersDB();
    
    // 设置定时任务，每隔5分钟重新加载数据库
    setInterval(() => {
        log('重新加载开发者数据库...', 'info');
        loadDevelopersDB();
    }, 5 * 60 * 1000); // 5分钟
    
    // 确保公共聊天文件存在
    if (!fs.existsSync(PUBLIC_CHAT_FILE)) {
        try {
            const initialMessage = {
                user: "系统",
                content: "聊天室已创建",
                timestamp: new Date().toISOString()
            };
            
            fs.writeFileSync(PUBLIC_CHAT_FILE, JSON.stringify([initialMessage], null, 2));
            log(`已创建聊天文件: ${PUBLIC_CHAT_FILE}`, 'success');
        } catch (err) {
            log(`无法创建聊天文件: ${err.message}`, 'error');
        }
    }
    
    // 确保API计数文件存在
    ensureKfitFile();
    
    log('服务器初始化完成', 'success');
});